package com.dycong.common.web.wrapper;

import lombok.extern.log4j.Log4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;

/**
 * Created by dycong on 15-5-4.
 * 可读取内容的输出流可配合 可重置/恢复读取流使用例如在doFilter时
 *    ResettableStreamHttpServletRequest wrappedRequest = new ResettableStreamHttpServletRequest(
     (HttpServletRequest) request);
    //使用输入流数据，之后 reset
     wrappedRequest.resetInputStream();
     //包装response 以使我们可以读取输出流内容
     ReadableHttpServletResponseWrapper httpServletResponse = new ReadableHttpServletResponseWrapper((HttpServletResponse) response);
     //doFilter
     chain.doFilter(wrappedRequest, httpServletResponse);
 */
@Log4j
public class ReadableHttpServletResponseWrapper extends HttpServletResponseWrapper {

    private ReadableOutputStream out;

    public ReadableHttpServletResponseWrapper(HttpServletResponse response) {
        super(response);
        try {
            OutputStream outputStream = response.getOutputStream();
            out = new ReadableOutputStream(outputStream);
        } catch (IOException e) {
            log.error("", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(out);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        //todo doFilter 等方法之后自定义数据的输出用的还是 out
        return out;
    }

    @Override
    public String toString() {
        try {
            return new String(out.byteArrayOutputStream.toByteArray(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public void addHeader(String name, String value) {
        log.trace("adding header: [" + name + "] = " + value);
        if (name.equals("Content-Length")) { //加上这个判断之后在response中addHeader才有效，Spring bug?
            //pass
        }else if(name.equals("Accept-Charset")){
            //pass
        }else{
            super.addHeader(name, value);
        }
    }


    protected static class ReadableOutputStream extends ServletOutputStream {
    //todo ByteArrayOutputStream 有一个 buf[] 用来 data is stored. The data can be retrieved using toByteArray() and toString()
        private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        private OutputStream out;

        public ReadableOutputStream(OutputStream out) {
            this.out = out;
        }


        @Override
        public void write(int b) throws IOException {
            // TODO: 2017/5/10 ByteArrayOutputStream write()方法并不会真的输出数据，只是将数据缓存起来 以供我们读取 Writes the specified byte to this byte array output stream.
            // TODO: 2017/5/10 out 真正输出数据， byteArrayOutputStream缓存数据
            byteArrayOutputStream.write(b);
            out.write(b);
        }

    }
}


